package com.my.stock.core;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Session;

import com.my.myTradeData.HibernateUtil;
import com.my.myTradeData.TechnicalAnalysisIndicators;
import com.my.myTradeData.TradeProduct;

public class Turtle {

	private static final int PARADAYS1 = 50;
	private static final int PARADAYS2 = 20;

	TradeInterface trade=new TradeService();

	Turtle(){
		
	}
	
	private List<KLine> dataList;

	private String sinaCode;

	private String tradeCode;

	private Double max;
	private Double min;

	private Double max20;
	private Double min20;

	private Double firstSignalPrice;
	private Double secondSignalPrice;
	private Double thirdSignalPrice;
	private Double fourthSignalPrice;

	private Integer direct;

	private Integer currentStep;

	private Integer number;

	private Double atr;

	public String getSinaCode() {
		return sinaCode;
	}

	public void setSinaCode(String sinaCode) {
		this.sinaCode = sinaCode;
	}

	public String getTradeCode() {
		return tradeCode;
	}

	public void setTradeCode(String tradeCode) {
		this.tradeCode = tradeCode;
	}

	public Double getMax() {
		return max;
	}

	public void setMax(Double max) {
		this.max = max;
	}

	public Double getMin() {
		return min;
	}

	public void setMin(Double min) {
		this.min = min;
	}

	public Double getMax20() {
		return max20;
	}

	public void setMax20(Double max20) {
		this.max20 = max20;
	}

	public Double getMin20() {
		return min20;
	}

	public void setMin20(Double min20) {
		this.min20 = min20;
	}

	public Double getFirstSignalPrice() {
		return firstSignalPrice;
	}

	public void setFirstSignalPrice(Double firstSignalPrice) {
		this.firstSignalPrice = firstSignalPrice;
	}

	public Double getSecondSignalPrice() {
		return secondSignalPrice;
	}

	public void setSecondSignalPrice(Double secondSignalPrice) {
		this.secondSignalPrice = secondSignalPrice;
	}

	public Double getThirdSignalPrice() {
		return thirdSignalPrice;
	}

	public void setThirdSignalPrice(Double thirdSignalPrice) {
		this.thirdSignalPrice = thirdSignalPrice;
	}

	public Double getFourthSignalPrice() {
		return fourthSignalPrice;
	}

	public void setFourthSignalPrice(Double fourthSignalPrice) {
		this.fourthSignalPrice = fourthSignalPrice;
	}

	public Integer getDirect() {
		return direct;
	}

	public void setDirect(Integer direct) {
		this.direct = direct;
	}

	public Integer getCurrentStep() {
		return currentStep;
	}

	public void setCurrentStep(Integer currentStep) {
		this.currentStep = currentStep;
	}

	public Integer getNumber() {
		return number;
	}

	public void setNumber(Integer number) {
		this.number = number;
	}

	public Double getAtr() {
		return atr;
	}

	public void setAtr(Double atr) {
		this.atr = atr;
	}

	public static double balance = 1000000 * 0.01;

	public static Turtle getInstance(String sinaCode) {
		return instanceMap.get(sinaCode);
	}

	public static void main(String[] args) throws NumberFormatException, Exception {
//		init();
	}

	public static void init(Date date) {
		instanceMap.clear();
		List<Turtle> tlist = HibernateUtil.selectAllTurtle();
		for (Turtle t : tlist) {
			t.updateTurtle(t.getSinaCode(),t.getTradeCode(),50,20,date);
			
			
			instanceMap.put(t.getSinaCode(), t);
			Session session = HibernateUtil.getSessionFactory().openSession();
			session.beginTransaction();
			session.saveOrUpdate(t);
			session.getTransaction().commit();
		}
	}

	private static Map<String, Turtle> instanceMap = new HashMap<String, Turtle>();

	public void updateTurtle(String name, String contractName, int paraDays, int paraDays2,Date date) {
		dataList = HibernateUtil.selectDatas(contractName, paraDays,date);
		
		max = TechnicalAnalysisIndicators.getMaxDayData(dataList, paraDays).getHigh();
		min = TechnicalAnalysisIndicators.getMinDayData(dataList, paraDays).getLow();

		max20 = TechnicalAnalysisIndicators.getMaxDayData(dataList, paraDays2).getHigh();
		min20 = TechnicalAnalysisIndicators.getMinDayData(dataList, paraDays2).getLow();

		this.sinaCode = name;
		this.atr = TechnicalAnalysisIndicators.getAtr(dataList, 26);
		
		this.number = (int) (balance / (atr ));
		if (this.number == 0) {
			this.number = 1;
		}
		this.tradeCode = contractName;
		
		// System.out.println(Dictionary.SinaDataDictionary.get(sinaCode) +
		// TechnicalAnalysisIndicators.majorTrend(dataList));
	}
	
	public boolean signal(double buyPrice, double sellPrice, double buylimit, double selllimit) {
		if(buyPrice==0 ||  sellPrice==0){
			return false;
		}
		boolean showSomeSignal = false;
		if (currentStep==null || currentStep == 0) {
			if (buyPrice >= max || sellPrice <= min) {
				if (buyPrice >= max) {
					direct = 0;
					firstSignalPrice = buyPrice;
//					trade.buyPosition(tradeCode, number, buylimit);
				} else {
					direct = 1;
					firstSignalPrice = sellPrice;
//					trade.sellPosition(tradeCode, number, selllimit);
				}
				currentStep = 1;
				showSomeSignal = true;
			}
		} else if (currentStep == 1) {
			if (direct == 0) {
				// have long position
				if (sellPrice < firstSignalPrice - atr) {
					// begin loss stop
					currentStep--;
					firstSignalPrice = null;
//					trade.longStop(tradeCode, number, buylimit);
					showSomeSignal = true;
				} else if (buyPrice > firstSignalPrice + atr) {
					// add position
					currentStep++;
					secondSignalPrice = buyPrice;
//					trade.buyPosition(tradeCode, number, selllimit);
					showSomeSignal = true;
				}
			} else {
				// have short position
				if (buyPrice > firstSignalPrice + atr) {
					// begin loss stop
					currentStep--;
					firstSignalPrice = null;
//					trade.shortStop(tradeCode, number, buylimit);
					showSomeSignal = true;
				} else if (sellPrice < firstSignalPrice - atr) {
					currentStep++;
					secondSignalPrice = sellPrice;
//					trade.buyPosition(tradeCode, number, selllimit);
					showSomeSignal = true;
				}
			}
		} else if (currentStep == 2) {
			if (direct == 0) {
				// have long position
				if (sellPrice < secondSignalPrice - atr) {
					// begin loss stop
					currentStep--;
					secondSignalPrice = null;
//					trade.longStop(tradeCode, number, buylimit);
					showSomeSignal = true;
				} else if (buyPrice > secondSignalPrice + atr) {
					// add position
					currentStep++;
					thirdSignalPrice = buyPrice;
//					trade.buyPosition(tradeCode, number, selllimit);
					showSomeSignal = true;
				}
			} else {
				// have short position
				if (buyPrice > secondSignalPrice + atr) {
					// begin loss stop
					currentStep--;
					secondSignalPrice = null;
//					trade.shortStop(tradeCode, number, buylimit);
					showSomeSignal = true;
				} else if (sellPrice < secondSignalPrice - atr) {
					currentStep++;
					thirdSignalPrice = sellPrice;
//					trade.buyPosition(tradeCode, number, selllimit);
					showSomeSignal = true;
				}
			}
		} else if (currentStep == 3) {
			if (direct == 0) {
				// have long position
				if (sellPrice < thirdSignalPrice - atr) {
					// begin loss stop
					currentStep--;
					thirdSignalPrice = null;
//					trade.longStop(tradeCode, number, buylimit);
					showSomeSignal = true;
				} else if (buyPrice > thirdSignalPrice + atr) {
					// add position
					currentStep++;
					fourthSignalPrice = buyPrice;
//					trade.buyPosition(tradeCode, number, selllimit);
					showSomeSignal = true;
				}
			} else {
				// have short position
				if (buyPrice > thirdSignalPrice + atr) {
					// begin loss stop
					currentStep--;
					thirdSignalPrice = null;
//					trade.shortStop(tradeCode, number, buylimit);
					showSomeSignal = true;
				} else if (sellPrice < thirdSignalPrice - atr) {
					currentStep++;
					fourthSignalPrice = sellPrice;
//					trade.buyPosition(tradeCode, number, selllimit);
					showSomeSignal = true;
				}
			}
		}

		if (showSomeSignal) {
			Session session = HibernateUtil.getSessionFactory().openSession();
			session.beginTransaction();
			session.saveOrUpdate(this);
			session.getTransaction().commit();
		}

		return showSomeSignal;
		// System.out.print(Dictionary.SinaDataDictionary.get(sinaCode) +
		// "      max:" + Math.round((max - close) / close * 100));
		// System.out.print("      min:" + Math.round((min - close) / close *
		// 100));
		// List<Position> plist = HibernateUtil.selectPosition(sinaCode);
		// if (plist.size() == 0) {
		// if (close >= max || close <= min) {
		// Position p = new Position();
		// p.setAtr(atr);
		// p.setSinaCode(sinaCode);
		// p.setBuyinPrice(close);
		// p.setBuyinNumber((int) Math.round(balance / (atr *
		// Dictionary.ATRTimesDictionary.get(sinaCode))));
		// p.setStep(1);
		// if (close >= max) {
		// p.setLongPosition(true);
		// } else {
		// p.setLongPosition(false);
		// }
		// Session session = HibernateUtil.getSessionFactory().openSession();
		// session.beginTransaction();
		// session.save(p);
		// session.getTransaction().commit();
		//
		// System.out.print(sinaCode + " show signal atr:" + (balance / (atr *
		// Dictionary.ATRTimesDictionary.get(sinaCode))));
		// return true;
		// } else {
		// return false;
		// }
		//
		// } else {
		//
		// if (plist.get(0).getLongPosition()) {
		//
		// if (close <= min20) {
		// Session session = HibernateUtil.getSessionFactory().openSession();
		// session.beginTransaction();
		// session.delete(plist.get(0));
		// System.out.print(sinaCode + " all cut ");
		// session.getTransaction().commit();
		// return true;
		// }
		//
		// if (close >= plist.get(0).getBuyinPrice() + plist.get(0).getStep() *
		// plist.get(0).getAtr()) {
		//
		// if (plist.get(0).getStep() >= 3) {
		//
		// } else {
		// Session session = HibernateUtil.getSessionFactory().openSession();
		// session.beginTransaction();
		// plist.get(0).setStep(plist.get(0).getStep() + 1);
		// session.update(plist.get(0));
		// session.getTransaction().commit();
		// System.out.print(sinaCode + " add ");
		// return true;
		// }
		//
		// } else if (close <= plist.get(0).getBuyinPrice() -
		// plist.get(0).getStep() * plist.get(0).getAtr()) {
		// Session session = HibernateUtil.getSessionFactory().openSession();
		// session.beginTransaction();
		// plist.get(0).setStep(plist.get(0).getStep() - 1);
		// if (plist.get(0).getStep() == 0) {
		// session.delete(plist.get(0));
		// } else {
		// session.update(plist.get(0));
		// }
		// session.getTransaction().commit();
		// System.out.print(sinaCode + " you lose ");
		// return true;
		// }
		//
		// } else {
		//
		// if (close >= max20) {
		// Session session = HibernateUtil.getSessionFactory().openSession();
		// session.beginTransaction();
		// session.delete(plist.get(0));
		// System.out.print(sinaCode + " all cut ");
		// session.getTransaction().commit();
		// return true;
		// }
		//
		// if (close <= plist.get(0).getBuyinPrice() - plist.get(0).getStep() *
		// plist.get(0).getAtr()) {
		// if (plist.get(0).getStep() >= 3) {
		//
		// } else {
		// Session session = HibernateUtil.getSessionFactory().openSession();
		// session.beginTransaction();
		// plist.get(0).setStep(plist.get(0).getStep() + 1);
		// session.update(plist.get(0));
		// session.getTransaction().commit();
		// System.out.print(sinaCode + " add ");
		// return true;
		// }
		// } else if (close >= plist.get(0).getBuyinPrice() +
		// plist.get(0).getStep() * plist.get(0).getAtr()) {
		// Session session = HibernateUtil.getSessionFactory().openSession();
		// session.beginTransaction();
		// plist.get(0).setStep(plist.get(0).getStep() - 1);
		//
		// if (plist.get(0).getStep() == 0) {
		// session.delete(plist.get(0));
		// } else {
		// session.update(plist.get(0));
		// }
		//
		// session.getTransaction().commit();
		// System.out.print(sinaCode + " you lose ");
		// return true;
		// }
		//
		// }
		//
		// return false;
		// }

	}

}
